package com.exm.collectcodenew.juc.waitnotify;

import java.util.ArrayList;

/**
 * 线程操作资源类Box，原意是资源类Box中的元素个数超过5时生产者线程要被调用wait方法被阻塞，当Box元素个数为0时消费者线程调用wait方法被阻塞，用if条件判断会导致虚假唤醒。
 */
public class FalseWakeTest {
    public static void main(String[] args) {
        Box box = new Box();
        //多个生产者线程生产元素
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                try {
                    box.add(1);
                    if(box.size()>5||box.size()<0){
                        System.out.println(Thread.currentThread().getName()+"执行后，box的size为大于5或者小于0，同步协作机制出错了，实际size为:"+box.size());
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            },"生产者"+i).start();
        }
        //多个消费者线程消费元素
        for (int j = 0; j < 10; j++) {
            new Thread(()->{
                try {
                    box.remove();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                if(box.size()>5||box.size()<0){
                    System.out.println(Thread.currentThread().getName()+"执行后，box的size为大于5或者小于0，同步协作机制出错了，实际size为:"+box.size());
                }
            },"消费者线程"+j).start();
        }

    }
    static class Box {
        private final int MAX = 5;
        private final ArrayList<Integer> list = new ArrayList<>();
        synchronized void add(int v) throws InterruptedException {
            if (list.size() == MAX) {
//            while (list.size() == MAX) {
                wait();
            }
            list.add(v);
            notifyAll();
        }
        synchronized int remove() throws InterruptedException {
            if (list.size() == 0) {
//            while (list.size() == 0) {
                wait();
            }
            int v = list.remove(0);
            notifyAll();
            return v;
        }
        synchronized int size() {
            return list.size();
        }
    }
}
